package handlers

import (
	"net/http"

	"github.com/devops-smartbot/devops-smartbot/services/api-gateway/internal/models"
	"github.com/devops-smartbot/devops-smartbot/services/api-gateway/internal/repository"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// KnowledgeHandler handles knowledge base HTTP requests
type KnowledgeHandler struct {
	repo repository.KnowledgeRepository
}

// NewKnowledgeHandler creates a new knowledge handler
func NewKnowledgeHandler(repo repository.KnowledgeRepository) *KnowledgeHandler {
	return &KnowledgeHandler{repo: repo}
}

// ListDocs handles GET /api/knowledge
func (h *KnowledgeHandler) ListDocs(c *gin.Context) {
	var params models.KnowledgeQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	docs, total, err := h.repo.List(c.Request.Context(), params)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"data": docs,
		"pagination": gin.H{
			"total":    total,
			"page":     params.Page,
			"pageSize": params.PageSize,
		},
	})
}

// GetDoc handles GET /api/knowledge/:id
func (h *KnowledgeHandler) GetDoc(c *gin.Context) {
	id := c.Param("id")

	doc, err := h.repo.GetByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if doc == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Document not found"})
		return
	}

	// Increment view count
	_ = h.repo.IncrementView(c.Request.Context(), id)

	c.JSON(http.StatusOK, doc)
}

// CreateDoc handles POST /api/knowledge
func (h *KnowledgeHandler) CreateDoc(c *gin.Context) {
	var req models.CreateKnowledgeRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Default status
	status := req.Status
	if status == "" {
		status = "published"
	}

	doc := &models.KnowledgeDoc{
		ID:       uuid.New().String(),
		Title:    req.Title,
		Content:  req.Content,
		Category: req.Category,
		Tags:     req.Tags,
		Author: models.Author{
			ID:       "system",
			Username: "admin",
		},
		Status: status,
	}

	if err := h.repo.Create(c.Request.Context(), doc); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, doc)
}

// UpdateDoc handles PUT /api/knowledge/:id
func (h *KnowledgeHandler) UpdateDoc(c *gin.Context) {
	id := c.Param("id")

	var req models.UpdateKnowledgeRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Get existing document
	doc, err := h.repo.GetByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if doc == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Document not found"})
		return
	}

	// Update fields
	if req.Title != nil {
		doc.Title = *req.Title
	}
	if req.Content != nil {
		doc.Content = *req.Content
	}
	if req.Category != nil {
		doc.Category = *req.Category
	}
	if req.Tags != nil {
		doc.Tags = req.Tags
	}
	if req.Status != nil {
		doc.Status = *req.Status
	}

	if err := h.repo.Update(c.Request.Context(), id, doc); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, doc)
}

// DeleteDoc handles DELETE /api/knowledge/:id
func (h *KnowledgeHandler) DeleteDoc(c *gin.Context) {
	id := c.Param("id")

	if err := h.repo.Delete(c.Request.Context(), id); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Document deleted successfully"})
}

// GetCategories handles GET /api/knowledge/categories
func (h *KnowledgeHandler) GetCategories(c *gin.Context) {
	categories, err := h.repo.GetCategories(c.Request.Context())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, categories)
}

// GetPopular handles GET /api/knowledge/popular
func (h *KnowledgeHandler) GetPopular(c *gin.Context) {
	limit := 10 // Default limit
	docs, err := h.repo.GetPopular(c.Request.Context(), limit)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, docs)
}

// CreateFromTicket handles POST /api/knowledge/from-ticket
func (h *KnowledgeHandler) CreateFromTicket(c *gin.Context) {
	var req struct {
		TicketID    string   `json:"ticketId" binding:"required"`
		Title       string   `json:"title" binding:"required"`
		Content     string   `json:"content" binding:"required"`
		Category    string   `json:"category"`
		Tags        []string `json:"tags"`
		RootCause   string   `json:"rootCause"`
		Solution    string   `json:"solution"`
		Prevention  string   `json:"prevention"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Build knowledge base content from ticket and AI analysis
	content := "# Problem Description\n\n" + req.Content + "\n\n"

	if req.RootCause != "" {
		content += "# Root Cause Analysis\n\n" + req.RootCause + "\n\n"
	}

	if req.Solution != "" {
		content += "# Solution\n\n" + req.Solution + "\n\n"
	}

	if req.Prevention != "" {
		content += "# Preventive Measures\n\n" + req.Prevention + "\n\n"
	}

	// Default category
	category := req.Category
	if category == "" {
		category = "Incident Resolution"
	}

	// Add source info to tags
	tags := req.Tags
	if tags == nil {
		tags = []string{}
	}
	tags = append(tags, "from-ticket:"+req.TicketID)

	// Create knowledge document
	doc := &models.KnowledgeDoc{
		ID:       uuid.New().String(),
		Title:    req.Title,
		Content:  content,
		Category: category,
		Tags:     tags,
		Author: models.Author{
			ID:       "system",
			Username: "admin",
		},
		Status: "published",
	}

	if err := h.repo.Create(c.Request.Context(), doc); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"success": true,
		"data":    doc,
		"message": "Knowledge document created successfully",
	})
}
